/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include "引擎数据类型.h"
#include "引擎枚举数据.h"

#include "S_Object.h"



EngineAPI_EXPORT S_Scene*	f_scene_创建(S_设备环境& ctx, uint32 key = 0);
EngineAPI_EXPORT void		f_scene_销毁(uint32 key);
EngineAPI_EXPORT void		f_scene_销毁2(S_Scene* scene);
EngineAPI_EXPORT S_Scene*	f_scene_get场景(uint32 key);
EngineAPI_EXPORT void		f_scene_创建世界(S_Scene* scene);

EngineAPI_EXPORT void		f_scene_渲染(S_Scene* scene);
EngineAPI_EXPORT void		f_scene_渲染世界(S_Scene* scene, const S_渲染参数& 渲染参数);


EngineAPI_EXPORT void f_scene_添加物体列表(S_Scene* scene, S_物体* ob);

EngineAPI_EXPORT void	f_scene_场景链接物体(uint32 sceneID, uint32 objectID);
EngineAPI_EXPORT void	f_scene_场景链接物体(S_Scene* scene, S_物体* object);
EngineAPI_EXPORT void	f_scene_添加物体(S_Scene* scene, S_物体* ob, E_场景物体容器类型 容器类型 = E_场景物体容器类型::e_集合);
EngineAPI_EXPORT void	f_scene_添加物体(S_Scene* scene, const std::vector<S_物体*>& ob);
EngineAPI_EXPORT void	f_scene_移除物体(S_Scene* scene, S_物体* ob);
EngineAPI_EXPORT void	f_scene_移除物体(S_Scene* scene, const std::vector<S_物体*>& ob);
EngineAPI_EXPORT void	f_scene_移除所有物体(S_Scene* scene, E_场景物体容器类型 容器类型);


EngineAPI_EXPORT std::set<S_物体*>& f_scene_get集合物体(S_Scene* scene);
EngineAPI_EXPORT std::list<S_物体*>& f_scene_get循序物体(S_Scene* scene);


void f_scene_更新变换约束(S_物体* ob);



EngineAPI_EXPORT void		f_scene_开启光追(S_Scene* scene, S_设备环境& ctx);
EngineAPI_EXPORT void       f_scene_销毁光追渲染器(S_Scene* scene);
EngineAPI_EXPORT void		f_scene_重构光追线管(S_Scene* scene, S_设备环境& ctx);
EngineAPI_EXPORT void		f_scene_添加光追材质着色器(S_Scene* scene, const std::string path, int32 loc);
EngineAPI_EXPORT void		f_scene_删除光追材质着色器(S_Scene* scene, int32 loc);
EngineAPI_EXPORT void		f_scene_重建着色器();
EngineAPI_EXPORT void       f_scene_更新物体渲染(S_Scene* scene, S_物体* object);
//void		f_scene_构建顶层光追加速结构(S_Scene* scene, S_OBArray* obs, S_设备环境& ctx);

EngineAPI_EXPORT void	f_scene_设置光追渲染采样(S_Scene* scene, S_RayRenderAttr& Attr);
EngineAPI_EXPORT void	f_scene_设置环境着色器(S_Scene* scene, int32 环境着色器ID);
EngineAPI_EXPORT void	f_scene_设置光追渲染器视口渲染(S_Scene* scene, bool 是否渲染);
EngineAPI_EXPORT void	f_scene_往渲染器里添加纹理(const S_纹理添加列队& 纹理加载信息, bool 对比路径 = false);
EngineAPI_EXPORT void	f_scene_从渲染器里移除纹理(const S_纹理添加列队& 纹理移除信息);

EngineAPI_EXPORT S_纹理* f_scene_创建纹理(S_Scene* scene, S_设备环境& ctx, std::u16string name, E_纹理分组类型 分组, S_纹理* tex = nullptr);
EngineAPI_EXPORT bool    f_scene_销毁纹理(S_Scene* scene, S_纹理* tex, E_纹理分组类型 分组);
EngineAPI_EXPORT void	f_scene_修改纹理(S_Scene* scene, S_纹理* tex, uvec3 分辨率, E_纹理分组类型 分组);

EngineAPI_EXPORT void    f_scene_重载渲染器绑定纹理(S_Scene* scene, S_纹理* tex);
EngineAPI_EXPORT void	f_scene_更新配置内部纹理(S_Scene* scene);

EngineAPI_EXPORT S_渲染参数	f_scene_开始渲染(S_Scene* scene, S_摄像机* camera, const vec2& size, const vec2& offset);

EngineAPI_EXPORT void		f_连接物理引擎车辆操控函数(S_Scene* scene, fun_物体async_p f);
EngineAPI_EXPORT void		f_连接渲染前更新函数(S_Scene* scene, fun_渲染前更新p f);




EngineAPI_EXPORT std::vector<S_物体*> f_scene_射线拾取(S_Scene* scene, const vec3& s, const vec3& e, const S_摄像机& camera, const S_Rect2Df& rect, const vec2& 屏幕坐标, float32* 最近坐标 = nullptr);

void f_scene_框选物体(S_物体* 待选物体, std::set<S_物体*>& 选择物体, const vec4 平面[5], const vec3 视锥[4][2]);
void f_scene_框选物体(S_物体* 待选物体, std::set<S_物体*>& 选择物体, const Mat44f 相机矩阵[2], const S_Rect2Df& view, const S_Bounding2& 框);

EngineAPI_EXPORT void				f_scene_拾取包围盒物体(std::set<S_物体*>& 选择物体, S_物体* 待选物体, const vec3 视线起点方向相机位置[3]);
EngineAPI_EXPORT S_物体拾取信息		f_scene_拾取物体网格(S_物体* 待选物体, uint32 槽, const vec3 视线起点方向相机位置[3], const S_摄像机& 摄像机);

EngineAPI_EXPORT float32	f_scene_拾取物体网格(S_物体* 待选物体, uint32 槽, const vec3 视线起点方向相机位置[3]);

EngineAPI_EXPORT S_物体拾取信息		f_scene_拾取网格点(const std::vector<S_物体*>& 物体, const S_摄像机& camera, const S_Rect2Df& rect, const vec2& 屏幕坐标, float32 拾取距离);
S_物体拾取信息		f_scene_拾取网格面(const std::vector<S_物体*>& 物体, const S_摄像机& camera, const S_Rect2Df& rect, const vec2& 屏幕坐标);


void f_scene_添加回调对象(S_Scene* scene, S_场景回调* call);
void f_scene_删除回调对象(S_Scene* scene, S_场景回调* call);


EngineAPI_EXPORT vec3				f_scene_构建屏幕射线(vec3 坐标, const S_摄像机& camera, const S_Rect2Df& rect, vec3 射线[2]);


EngineAPI_EXPORT void	f_scene_渲染器GPU内存映射();
EngineAPI_EXPORT void	f_scene_渲染器GPU内存解映射();
EngineAPI_EXPORT void	f_scene_渲染器分配GPU内存();
EngineAPI_EXPORT void    f_scene_物体GPU内存分配();


EngineAPI_EXPORT uint32	f_scene_渲染器分配平行光内存(S_Scene* scene, uint32 num = 1);
EngineAPI_EXPORT S_GPU内存块	f_scene_渲染器分配点光源内存(S_Scene* scene, uint32 num = 1);
EngineAPI_EXPORT uint32	f_scene_渲染器分配区域光内存(S_Scene* scene, uint32 num = 1);
EngineAPI_EXPORT uint32	f_scene_渲染器分配聚光灯内存(S_Scene* scene, uint32 num = 1);

EngineAPI_EXPORT void	f_scene_渲染器设置平行光(S_Scene* scene, uint32 ID, const S_LightParallel& ligth);
EngineAPI_EXPORT void	f_scene_渲染器设置平行光启用(S_Scene* scene, uint32 ID, const bool e);
EngineAPI_EXPORT void	f_scene_渲染器设置点光源(S_Scene* scene, uint32 ID, const S_LightPoint& ligth);
EngineAPI_EXPORT void	f_scene_渲染器设置点光源启用(S_Scene* scene, uint32 ID, const bool e);
EngineAPI_EXPORT void	f_scene_渲染器设置聚光灯(S_Scene* scene, uint32 ID, const S_LightSpot& ligth);
EngineAPI_EXPORT void	f_scene_渲染器设置聚光灯启用(S_Scene* scene, uint32 ID, const bool e);
EngineAPI_EXPORT void	f_scene_渲染器设置区域光(S_Scene* scene, uint32 ID, const S_LightArea& ligth);
EngineAPI_EXPORT void	f_scene_渲染器设置区域光启用(S_Scene* scene, uint32 ID, const bool e);




EngineAPI_EXPORT void	f_scene_渲染器启用预览(S_Scene* scene);
EngineAPI_EXPORT void	f_scene_渲染器关闭预览(S_Scene* scene);
EngineAPI_EXPORT void	f_scene_渲染器启用渲染(S_Scene* scene);
EngineAPI_EXPORT void	f_scene_渲染器关闭渲染(S_Scene* scene);
EngineAPI_EXPORT void	f_scene_set渲染器渲染预览模式(S_Scene* scene, E_RenderLayerType 渲染预览模式);
EngineAPI_EXPORT void	f_scene_set渲染器渲染层(S_Scene* scene, uint32 layers);


EngineAPI_EXPORT void	f_scene_构建光追加速结构(S_Scene* scene);


EngineAPI_EXPORT void    f_render_刷新渲染(S_Scene* scene);

EngineAPI_EXPORT void	f_render_绑定参数(S_摄像机* camera, GLSL_RenderFrame& 帧渲染参数, S_纹理& tex, S_渲染世界* 世界, S_光追后端* 光追后端);
EngineAPI_EXPORT void	f_render_更新参数(GLSL_RenderFrame& 帧渲染参数, S_渲染世界* 世界, S_光追后端* 光追后端);



EngineAPI_EXPORT S_渲染世界* f_world_创建渲染世界(S_设备环境& ctx);
EngineAPI_EXPORT void		f_world_销毁渲染世界(S_渲染世界* 世界);

EngineAPI_EXPORT void f_world_添加渲染层(S_渲染世界* 世界, S_渲染层* 层, uint32 loc);
EngineAPI_EXPORT void f_world_更新绑定(S_渲染世界* 世界);
EngineAPI_EXPORT void f_world_更新输出纹理(S_渲染世界* 世界, uvec2 分辨率, uint32 图层位域);
EngineAPI_EXPORT void f_world_更新灯光(S_渲染世界* 世界);


EngineAPI_EXPORT void f_world_销毁渲染层(S_渲染世界* 世界, uint32 s, uint32 e = -1);



EngineAPI_EXPORT bool    f_scene_销毁渲染器纹理(S_Scene* scene, uint32 保留数量, E_纹理分组类型 分组);

bool    f_scene_光栅渲染(S_Scene* scene);




